package lol.clann.minecraft.springboot.plugin.hook;

import lol.clann.minecraft.springboot.api.spi.bean.BeanRegister;
import lol.clann.minecraft.springboot.api.context.PluginContext;
import lol.clann.minecraft.springboot.api.model.core.Plugin;
import lol.clann.minecraft.springboot.api.utils.BeanRegisterUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 注册插件直接提供的bean,并扫描插件的bean
 *
 * @author pyz
 * @date 2019/4/8 10:46 PM
 */
@Slf4j
@Component
public class BeanSPI implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//      注册插件直接提供的bean
        for (BeanRegister beanRegister : ServiceLoader.load(BeanRegister.class)) {
            Map<String, Object> map = beanRegister.getBasePackages();
            if (map == null) {
                continue;
            }
            for (Map.Entry<String, Object> en : map.entrySet()) {
                BeanRegisterUtils.register(en.getKey(), en.getValue(), registry);
            }
        }
//      用插件的basepackage进行包扫描
        Set<String> basePackageSet = new HashSet<>();
        for (Plugin plugin : PluginContext.getPlugins()) {
            basePackageSet.addAll(plugin.getBasePackages());
        }
        if (basePackageSet.isEmpty()) {
            LOGGER.warn("not base packages find!");
            return;
        }
        String[] basePackages = basePackageSet.toArray(new String[basePackageSet.size()]);
        LOGGER.info("start scan bean definition in basepackages:" + Arrays.toString(basePackages));
        long start = System.currentTimeMillis();
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
        scanner.scan(basePackages);
        long end = System.currentTimeMillis();
        LOGGER.info("cost " + (end - start) + " ms");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}
